package com.liziba.unsafe;

import com.liziba.unsafe.pojo.User;
import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * <p>
 *      CAS操作示例
 * </p>
 *
 * @Author: Liziba
 * @Date: 2021/5/24 22:18
 */
public class OperateCASExample {

    /**
     * CAS == compare and swap(比较并替换)
     * 当需要改变的值为期望值的时候，就替换为新的值，是原子（不可再分割）操作。Java中大量的并发框架底层使用到了CAS操作。
     * 优势：无锁操作，减少线程切换带来的开销
     * 缺点：CAS容易在并发的情况下失败从而引发性能问题，也存在ABA问题。
     *
     * Unsafe中提供了三个方法
     * 1、compareAndSwapInt
     * 2、compareAndSwapLong
     * 3、compareAndSwapObject
     *
     */
    public static void operateCASUseUnsafe() throws Exception {

        User user = new User(1, "李子捌");
        System.out.println("pre user value: " + user);

        Unsafe unsafe = UnsafeFactory.getUnsafe();
        Field id = user.getClass().getDeclaredField("id");
        Field name = user.getClass().getDeclaredField("name");
        // 获取ID字段的内存偏移量
        long idFieldOffset = unsafe.objectFieldOffset(id);
        // 获取name字段的内存偏移量
        long nameFieldOffset = unsafe.objectFieldOffset(name);
        // 如果ID的期望值是1，则修改为18  success
        unsafe.compareAndSwapInt(user, idFieldOffset, 1, 18);
        // 如果name的期望值是小荔枝，则修改为李子柒  fail
        unsafe.compareAndSwapObject(user, nameFieldOffset, "小荔枝", "李子柒");
        // 输出修改的user对象
        System.out.println("post user value: " + user);

    }


    public static void main(String[] args) {
        try {
            OperateCASExample.operateCASUseUnsafe();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
